package cn.wildfire.chat.kit.preview;

import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.drawable.BitmapDrawable;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.Toast;
import android.widget.VideoView;

import com.github.chrisbanes.photoview.PhotoView;
import com.sourcemuch.im.caiba.R;

import java.io.File;
import java.io.FileInputStream;
import java.lang.ref.WeakReference;
import java.util.List;

import androidx.annotation.NonNull;
import androidx.viewpager.widget.PagerAdapter;
import androidx.viewpager.widget.ViewPager;
import cn.wildfire.chat.app.Config;
import cn.wildfire.chat.app.extendsion.https.OkHttpRequest;
import cn.wildfire.chat.app.extendsion.https.ReqCallBack;
import cn.wildfire.chat.app.extendsion.ui.TipDialog;
import cn.wildfire.chat.app.extendsion.ui.ToastTip;
import cn.wildfire.chat.app.extendsion.utils.FileUtils;
import cn.wildfire.chat.kit.GlideApp;
import cn.wildfire.chat.kit.conversation.message.model.UiMessage;
import cn.wildfire.chat.kit.third.utils.UIUtils;
import cn.wildfire.chat.kit.utils.DownloadManager;
import cn.wildfire.chat.kit.widget.ViewPagerFixed;
import cn.wildfirechat.message.ImageMessageContent;
import cn.wildfirechat.message.VideoMessageContent;
import cn.wildfirechat.message.core.MessageContentType;

/**
 * @author imndx
 */
public class MMPreviewActivity extends Activity {
    private SparseArray<View> views;
    private View currentVideoView;

    private static int currentPosition = -1;
    private static List<UiMessage> messages;
    private boolean pendingPreviewInitialMedia;

    private final PagerAdapter pagerAdapter = new PagerAdapter() {

        @NonNull
        @Override
        public Object instantiateItem(@NonNull ViewGroup container, int position) {
            View view;
            UiMessage message = messages.get(position);
            if (message.message.content.getType() == MessageContentType.ContentType_Image) {
                view = LayoutInflater.from(MMPreviewActivity.this).inflate(R.layout.preview_photo, null);
            } else {
                view = LayoutInflater.from(MMPreviewActivity.this).inflate(R.layout.preview_video, null);
            }

            container.addView(view);
            views.put(position % 3, view);
            if (pendingPreviewInitialMedia) {
                preview(view, message);
            }
            return view;
        }

        @Override
        public void destroyItem(ViewGroup container, int position, @NonNull Object object) {
            // do nothing ?
            container.removeView((View) object);
        }

        @Override
        public int getCount() {
            return messages == null ? 0 : messages.size();
        }

        @Override
        public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
            return view == object;
        }
    };

    final ViewPager.OnPageChangeListener pageChangeListener = new ViewPager.OnPageChangeListener() {
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
            // TODO 可以在此控制透明度
        }

        @Override
        public void onPageSelected(int position) {
            View view = views.get(position % 3);
            if (view == null) {
                // pending layout
                return;
            }
            if (currentVideoView != null) {
                resetVideoView(currentVideoView);
                currentVideoView = null;
            }
            UiMessage message = messages.get(position);
            preview(view, message);
        }

        @Override
        public void onPageScrollStateChanged(int state) {

        }
    };

    private void preview(View view, UiMessage message) {
        if (message.message.content.getType() == MessageContentType.ContentType_Image) {
            previewImage(view, message);
        } else {
            previewVideo(view, message);
        }
    }

    private void resetVideoView(View view) {
        PhotoView photoView = view.findViewById(R.id.photoView);
        ProgressBar loadingProgressBar = view.findViewById(R.id.loading);
        ImageView playButton = view.findViewById(R.id.btnVideo);
        VideoView videoView = view.findViewById(R.id.videoView);

        photoView.setVisibility(View.VISIBLE);
        loadingProgressBar.setVisibility(View.GONE);
        playButton.setVisibility(View.VISIBLE);
        videoView.stopPlayback();
        videoView.setVisibility(View.INVISIBLE);
    }

    private void previewVideo(View view, UiMessage message) {

        VideoMessageContent content = (VideoMessageContent) message.message.content;
        PhotoView photoView = view.findViewById(R.id.photoView);
        photoView.setImageBitmap(content.getThumbnail());

        VideoView videoView = view.findViewById(R.id.videoView);
        videoView.setVisibility(View.INVISIBLE);

        ProgressBar loadingProgressBar = view.findViewById(R.id.loading);
        loadingProgressBar.setVisibility(View.GONE);

        ImageView btn = view.findViewById(R.id.btnVideo);
        btn.setVisibility(View.VISIBLE);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                btn.setVisibility(View.GONE);
                if (TextUtils.isEmpty(content.localPath)) {
                    File videoFile = new File(Config.VIDEO_SAVE_DIR, message.message.messageUid + ".mp4");
                    if (!videoFile.exists()) {
                        view.setTag(message.message.messageUid + "");
                        ProgressBar loadingProgressBar = view.findViewById(R.id.loading);
                        loadingProgressBar.setVisibility(View.VISIBLE);
                        final WeakReference<View> viewWeakReference = new WeakReference<>(view);
                        DownloadManager.get().download(content.remoteUrl, Config.VIDEO_SAVE_DIR, message.message.messageUid + ".mp4", new DownloadManager.OnDownloadListener() {
                            @Override
                            public void onSuccess(File file) {
                                UIUtils.postTaskSafely(() -> {
                                    View targetView = viewWeakReference.get();
                                    if (targetView != null && (message.message.messageUid + "").equals(targetView.getTag())) {
                                        targetView.findViewById(R.id.loading).setVisibility(View.GONE);
                                        playVideo(targetView, file.getAbsolutePath());
                                    }
                                });
                            }

                            @Override
                            public void onProgress(int progress) {
                                // TODO update progress
                                Log.e(MMPreviewActivity.class.getSimpleName(), "video downloading progress: " + progress);
                            }

                            @Override
                            public void onFail() {
                                View targetView = viewWeakReference.get();
                                UIUtils.postTaskSafely(() -> {
                                    if (targetView != null && (message.message.messageUid + "").equals(targetView.getTag())) {
                                        targetView.findViewById(R.id.loading).setVisibility(View.GONE);
                                        targetView.findViewById(R.id.btnVideo).setVisibility(View.VISIBLE);
                                    }
                                });
                            }
                        });
                    } else {
                        playVideo(view, videoFile.getAbsolutePath());
                    }
                } else {
                    playVideo(view, content.localPath);
                }
            }
        });
    }

    private void playVideo(View view, String videoUrl) {
        VideoView videoView = view.findViewById(R.id.videoView);
        videoView.setVisibility(View.INVISIBLE);

        PhotoView photoView = view.findViewById(R.id.photoView);
        photoView.setVisibility(View.GONE);

        ImageView btn = view.findViewById(R.id.btnVideo);
        btn.setVisibility(View.GONE);

        ProgressBar loadingProgressBar = view.findViewById(R.id.loading);
        loadingProgressBar.setVisibility(View.GONE);
        view.findViewById(R.id.loading).setVisibility(View.GONE);
        currentVideoView = view;

        videoView.setVisibility(View.VISIBLE);
        videoView.setVideoPath(Uri.decode(videoUrl));
        videoView.setOnErrorListener((mp, what, extra) -> {
            Toast.makeText(MMPreviewActivity.this, "play error", Toast.LENGTH_SHORT).show();
            resetVideoView(view);
            return true;
        });
        videoView.setOnCompletionListener(mp -> resetVideoView(view));
        videoView.start();

    }

    private void previewImage(View view, UiMessage message) {
        ImageMessageContent content = (ImageMessageContent) message.message.content;
        String path = TextUtils.isEmpty(content.localPath) ? content.remoteUrl : content.localPath;
        PhotoView photoView = view.findViewById(R.id.photoView);
        GlideApp.with(MMPreviewActivity.this).load(path)
                .placeholder(new BitmapDrawable(getResources(), content.getThumbnail()))
                .into(photoView);
        try {
            // 保存功能
            String[] values = path.split("[////]");
            @SuppressLint("SdCardPath") String savPath = Config.PHOTO_SAVE_DIR;
            FileUtils.createDirectory(savPath);
            String checkSavPath = savPath + (values[values.length - 1] + ".jpg");
            File file = new File(checkSavPath);
            Button saveBut = view.findViewById(R.id.saveBut);
            final boolean saved = file.exists();
            if (saved) {
                String time = String.valueOf(System.currentTimeMillis());
                checkSavPath = savPath + (values[values.length - 1] + (time.substring(time.length() - 6)) + ".jpg");
                file = new File(checkSavPath);
            }
            final String cachePath = checkSavPath;
            saveBut.setText(getString(R.string.save_title));
            File finalFile = file;
            saveBut.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                            String[] permissions = new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE};
                            requestPermissions(permissions, 100);
                            for (int i = 0; i < permissions.length; i++) {
                                if (checkSelfPermission(permissions[i]) != PackageManager.PERMISSION_GRANTED) {
                                    ToastTip.tip("请允许申请文件读写等权限!");
                                    return;
                                }
                            }
                        }
                    }
                    // 自己发出的文件
                    if (!path.startsWith("http")) {
                        try {
                            FileUtils.savePicAsync(new FileInputStream(path), cachePath, new FileUtils.OnFileSaveListener() {
                                @Override
                                public void onSaved(boolean success) {
                                    ToastTip.tip(getString(success ? R.string.save_success : R.string.save_failure));
                                    if (success) {
                                        sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(finalFile)));
                                    }
                                    finish();
                                }
                            });
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        return;
                    }
                    TipDialog tipDialog = new TipDialog(MMPreviewActivity.this, "" + getString(R.string.save_on));
                    tipDialog.setTitle("");
                    tipDialog.show();
                    OkHttpRequest.getNewInstance(MMPreviewActivity.this).downLoadFile(path, cachePath, new ReqCallBack<Object>() {
                        @Override
                        public void onReqSuccess(Object result) {
                            tipDialog.dismiss();
                            ToastTip.tip(getString(R.string.save_success));
                            sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(finalFile)));
                            finish();
                        }

                        @Override
                        public void onReqFailed(String errorMsg) {
                            tipDialog.dismiss();
                            ToastTip.tip(getString(R.string.save_failure));
                            finish();
                        }
                    });
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_mm_preview);
        views = new SparseArray<>(3);
        final ViewPagerFixed viewPager = findViewById(R.id.viewPager);
        viewPager.setAdapter(pagerAdapter);
        viewPager.setOffscreenPageLimit(1);
        viewPager.addOnPageChangeListener(pageChangeListener);
        if (currentPosition == 0) {
            viewPager.post(() -> pageChangeListener.onPageSelected(0));
        } else {
            viewPager.setCurrentItem(currentPosition);
            pendingPreviewInitialMedia = true;
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        messages = null;
    }

    public static void startActivity(Context context, List<UiMessage> messages, int current) {
        if (messages == null || messages.isEmpty()) {
            Log.w(MMPreviewActivity.class.getSimpleName(), "message is null or empty");
            return;
        }
        MMPreviewActivity.messages = messages;
        MMPreviewActivity.currentPosition = current;
        Intent intent = new Intent(context, MMPreviewActivity.class);
        context.startActivity(intent);
    }

}
